package com.tomorrow.runner.data;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import cn.sucun.android.log.Log;

/**
 * There is used to help create database
 */
public class DatabaseHelper extends SQLiteOpenHelper {

	private static final String LOG_TAG = "DatabaseHelper";

	/**
	 * the DBBuilder define four function to help createTable , dropTable ,
	 * updateTable,getTableName sql table
	 */
	public interface DBBuilder {
		void createTable(Context context, SQLiteDatabase db);

		void dropTable(SQLiteDatabase fb);

		boolean updateTable(SQLiteDatabase db, int oldVersion, int newVersion);

		String getTableName();
	}

	/**
	 * the DBBuilder interface instance , it instant the drop and getTableName
	 * function, it do not instant the createTable function,this function will
	 * instance in the Object class which is the BaseColumns to Save
	 * 
	 */
	public static abstract class AbsDBBuilder implements DBBuilder {
		private final String TABLE_NAME;

		protected AbsDBBuilder(String tableName) {
			TABLE_NAME = tableName;
		}

		@Override
		public void dropTable(SQLiteDatabase db) {
			db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
		}

		@Override
		public boolean updateTable(SQLiteDatabase db, int oldVersion,
								   int newVersion) {
			return false;
		}

		@Override
		public String getTableName() {
			return TABLE_NAME;
		}
	}

	private final Context mContext;
	private final int mDbVersion;
	private final DBBuilder[] mBuilders;

	public DatabaseHelper(Context context, String dbName, int dbVersion,
						  DBBuilder... builders) {
		super(context, dbName, null, dbVersion);
		mContext = context;
		mDbVersion = dbVersion;
		mBuilders = builders;
	}

	/**
	 * when use getReadableDatabase  or getWritableDatabase，会判断指定的数据库是否存在，
	 * 不存在则调SQLiteDatabase.create创建， onCreate只在数据库第一次创建时才执行
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		if (mBuilders == null) {
			return;
		}
		for (DBBuilder builder : mBuilders) {
			builder.createTable(mContext, db);
		}
	}

	/**
	 * 根据dbVersion更新数据库
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		int version = oldVersion;

		if (version < mDbVersion) {
			db.beginTransaction();
			try {
				// XXX Do something to transact old DB to new version.
				boolean result = true;
				for (DBBuilder builder : mBuilders) {
					result = result
							&& builder.updateTable(db, oldVersion, newVersion);
				}
				if (result) {
					version = mDbVersion;
				}
				db.setTransactionSuccessful();
			} catch (SQLException e) {
				// Old version remains, which means we wipe old data
				Log.e(LOG_TAG, "Update DB failed.", e);
			} finally {
				db.endTransaction();
			}
		}

		if (version != mDbVersion && mBuilders != null) {
			Log.w(LOG_TAG, "Destroying all old data.");
			for (DBBuilder builder : mBuilders) {
				builder.dropTable(db);
			}
			onCreate(db);
		}
	}

}
